home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / wpj1_6.zip / EDITPRO.ZIP / EDITPRO.C < prev    next >
C/C++ Source or Header  |  1993-04-30  |  25KB  |  623 lines

  1.  
  2. /* EditPro Version 1.00 Copyright (c) 1993 Eric Grass */
  3. /* QuickCase:W KNB Version 1.00 */
  4.  
  5. #include "EDITPRO.h"
  6. // Turn off some stuff to speed up compile time...
  7. #define NORESOURCE    TRUE
  8. #define    NOATOM        TRUE
  9. #define    NOLANGUAGE    TRUE
  10. #define    OEMRESOURCE    TRUE
  11. #define    NORASTEROPS    TRUE
  12. #define    NOMETAFILE    TRUE
  13. #define    NOTEXTMETRIC    TRUE
  14. #define    NOGDICAPMASKS    TRUE
  15. #define    NODRAWTEXT    TRUE
  16. #define    NOWH        TRUE
  17. #define    NODEFERWINDOWPOS TRUE
  18. #define    NOCLIPBOARD    TRUE
  19. #define    NOSYSMETRICS    TRUE
  20. #define    NOSYSCOMMANDS    TRUE
  21. #define    NOKANJI        TRUE
  22. #define    NOSOUND        TRUE
  23. #define    NOCOMM        TRUE
  24. #define    NOPROFILER    TRUE
  25.  
  26. char    szFileName[256] = "*.*";
  27. char    szFileTitle[14];
  28. WORD    xoffset = 0, NoLines = 0, CurrentLineNo = 0;
  29. WORD    nTabStop = 8, TabStopLngth;
  30. char    szSpace[] = " ";
  31. WORD    textheight = 0, spacewidth = 0;
  32. RECT    rect;
  33. HANDLE    hFirstLine, hCurrentLine, hCurrentFont;
  34.  
  35. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
  36. {
  37.  /***********************************************************************/
  38.  /* HANDLE hInstance;       handle for this instance                    */
  39.  /* HANDLE hPrevInstance;   handle for possible previous instances      */
  40.  /* LPSTR  lpszCmdLine;     long pointer to exec command line           */
  41.  /* int    nCmdShow;        Show code for main window display           */
  42.  /***********************************************************************/
  43.  
  44.  MSG        msg;           /* MSG structure to store your messages        */
  45.  int        nRc;           /* return value from Register Classes          */
  46.  
  47.  strcpy(szAppName, "EDITPRO");
  48.  hInst = hInstance;
  49.  if(!hPrevInstance)
  50.    {
  51.     /* register window classes if first instance of application         */
  52.     if ((nRc = nCwRegisterClasses()) == -1)
  53.       {
  54.        /* registering one of the windows failed                         */
  55.        LoadString(hInst, IDS_ERR_REGISTER_CLASS, szString, sizeof(szString));
  56.        MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
  57.        return nRc;
  58.       }
  59.    }
  60.  
  61.  /* create application's Main window                                    */
  62.  hWndMain = CreateWindow(
  63.                 szAppName,               /* Window class name           */
  64.                 "EditPro",               /* Window's title              */
  65.                 WS_CAPTION      |        /* Title and Min/Max           */
  66.                 WS_SYSMENU      |        /* Add system menu box         */
  67.                 WS_MINIMIZEBOX  |        /* Add minimize box            */
  68.                 WS_MAXIMIZEBOX  |        /* Add maximize box            */
  69.                 WS_THICKFRAME   |        /* thick sizeable frame        */
  70.                 WS_VSCROLL      |        /* add vertical scroll bar     */
  71.                 WS_HSCROLL      |        /* add horizontal scroll bar   */
  72.                 WS_CLIPCHILDREN |         /* don't draw in child windows areas */
  73.                 WS_OVERLAPPED,
  74.                 CW_USEDEFAULT, 0,        /* Use default X, Y            */
  75.                 CW_USEDEFAULT, 0,        /* Use default X, Y            */
  76.                 NULL,                    /* Parent window's handle      */
  77.                 NULL,                    /* Default to Class Menu       */
  78.                 hInst,                   /* Instance of window          */
  79.                 NULL);                   /* Create struct for WM_CREATE */
  80.  
  81.  
  82.  if(hWndMain == NULL)
  83.    {
  84.     LoadString(hInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
  85.     MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
  86.     return IDS_ERR_CREATE_WINDOW;
  87.    }
  88.  
  89.  ShowWindow(hWndMain, nCmdShow);            /* display main window      */
  90.  
  91.  hAccel = LoadAccelerators(hInst, szAppName);
  92.  
  93.  while(GetMessage(&msg, NULL, 0, 0))        /* Until WM_QUIT message    */
  94.    {
  95.     if(TranslateAccelerator(hWndMain, hAccel, &msg))
  96.       continue;
  97.     TranslateMessage(&msg);
  98.     DispatchMessage(&msg);
  99.    }
  100.  
  101.  /* Do clean up before exiting from the application                     */
  102.  CwUnRegisterClasses();
  103.  return msg.wParam;
  104. } /*  End of WinMain                                                    */
  105. /************************************************************************/
  106. /*                                                                      */
  107. /* Main Window Procedure                                                */
  108. /*                                                                      */
  109. /* This procedure provides service routines for the Windows events      */
  110. /* (messages) that Windows sends to the window, as well as the user     */
  111. /* initiated events (messages) that are generated when the user selects */
  112. /* the action bar and pulldown menu controls or the corresponding       */
  113. /* keyboard accelerators.                                               */
  114. /*                                                                      */
  115. /************************************************************************/
  116.  
  117. LONG FAR PASCAL WndProc(HWND hWnd, WORD Message, WORD wParam, LONG lParam)
  118. {
  119.  HMENU      hMenu=0;            /* handle for the menu                 */
  120.  HBITMAP    hBitmap=0;          /* handle for bitmaps                  */
  121.  HDC        hDC;                /* handle for the display device       */
  122.  PAINTSTRUCT ps;                /* holds PAINT information             */
  123.  int        nRc=0;              /* return code                         */
  124.  WORD        CurrentLine, hTemp, hTemp2, j, i, hFile, hTemp3, hOldCursor;
  125.  LPSTR        lpLine, lpstrTemp;
  126.  DWORD        dwTemp;
  127.  OFSTRUCT    ofs;
  128.  
  129.  switch (Message)
  130.    {
  131.     case WM_COMMAND:
  132.          /* The Windows messages for action bar and pulldown menu items */
  133.          /* are processed here.                                         */
  134.          switch (wParam)
  135.            {
  136.             case IDM_F_OPENT:
  137.                 if( hFirstLine)    // If a file is already loaded, free it's memory...
  138.                     SendMessage( hWnd, WM_COMMAND, IDM_F_CLOSE, NULL);
  139.         hOldCursor = SetCursor( LoadCursor( NULL, IDC_WAIT));
  140.         FileRoutine();
  141.              if( ( hFile = OpenFile( szFileName, &ofs, OF_PROMPT | OF_READ)) != -1)
  142.              {    if( (unsigned long)( dwTemp = _llseek( hFile, 0, 2)) > 0x00003FFFL)
  143.                      dwTemp = 0x00003FFFL;
  144.                  // Store the original buffer size in hDC.
  145.                  hDC = (WORD) dwTemp;
  146.                  _llseek( hFile, 0, 0);
  147.             if( !( lpstrTemp = GlobalLock( hTemp = GlobalAlloc( GMEM_MOVEABLE, dwTemp))))
  148. CANTMAKEBUFF:        {    CreateMsgBox( hWnd, IDS_ERR_FILE2BIG);
  149.                      _lclose( hFile);
  150.                      PostMessage( hWnd, WM_CLOSE, hFirstLine = hCurrentLine = NULL, NULL);
  151.                      return 0L;
  152.             }
  153.             if( !( lpLine = (LPSTR) GlobalLock( hTemp2 = GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE, LINELNGTH))))
  154.             {    CreateMsgBox( hWnd, IDS_ERR_FILE2BIG);
  155.                 GlobalUnlock( hTemp);
  156.                 GlobalFree( hTemp);
  157.                 _lclose( hFile);
  158.                      hFirstLine = hCurrentLine = 0;
  159.                 return 0L;
  160.             }
  161.             CurrentLine = 1;
  162.             hFirstLine = hCurrentLine = hTemp2;
  163.             (WORD) lpLine += FIRSTCHAR;    // skip first four bytes & copy up to carriage return
  164.             hTemp3 = NULL;
  165.             // While not at End Of File, read the file into the buffer...
  166. READFILE:            _asm
  167.             {    MOV    AH, 3FH
  168.                 MOV    BX, hFile
  169.                 MOV    CX, WORD PTR hDC    // = Buffer Size
  170.                 MOV    DX, WORD PTR lpstrTemp
  171.                 PUSH    DS
  172.                 MOV    DS, WORD PTR lpstrTemp+2
  173.                 CALL    DOS3Call
  174.                 POP    DS
  175.                 JNC    READOKAY    // Error
  176.                 JMP    STOPREADING
  177. READOKAY:            OR    AX, AX
  178.                 JNZ    NOTTHEREYET
  179.                 JMP    STOPREADING    // End Of File
  180. NOTTHEREYET:            MOV    WORD PTR dwTemp, AX    // = Actual # of bytes read
  181.                 MOV    WORD PTR dwTemp+2, 0
  182.             }
  183.              // While not at End of Buffer...
  184.              while( (WORD) lpstrTemp < (WORD) dwTemp)
  185.             {       if( (WORD) lpLine == LINELNGTH)
  186.                 {    OkayMessageBoxf( hWnd, "Line %d is too long and will be truncated.", CurrentLine);
  187.                     (WORD) lpLine = 2;
  188.                     // Find next carriage return
  189.                     while( (WORD) lpstrTemp < (WORD) dwTemp && (char) *lpstrTemp != '\r')
  190.                         ++((WORD)lpstrTemp);
  191.                 }
  192.                 if( (WORD) lpstrTemp < (WORD) dwTemp)
  193.                 {    if( (char) *lpstrTemp == '\r')    // if carriage return found,
  194.                     {    if( (WORD) ++lpstrTemp < (WORD) dwTemp && (char) *lpstrTemp == '\n')
  195.                             ++((WORD) lpstrTemp); // discard the extra chars on the line
  196.                         // Save the length of the line
  197.                         _asm    MOV    ES, WORD PTR lpLine+2
  198.                         _asm    MOV    AX, WORD PTR lpLine
  199.                         _asm    DEC    AX
  200.                         _asm    MOV    BYTE PTR ES:[FIRSTCHAR-1], AL
  201.                         // Reallocate the line to minimum size...
  202.                         if( !GlobalReAlloc( hTemp2, (DWORD)((WORD) lpLine), GMEM_MOVEABLE))
  203.                             goto OUTOFMEM;
  204.                         hTemp3 = hTemp2;    // save previous line handle & allocate a new line.
  205.                         (WORD) lpLine = 2;    //            /
  206.                         if( !( lpLine = (LPSTR) GlobalLock( (WORD) *lpLine = hTemp2 = GlobalAlloc( GMEM_MOVEABLE, LINELNGTH))))
  207. OUTOFMEM:                        {    CreateMsgBox( hWnd, IDS_ERR_FILE2BIG);
  208.                             GlobalUnlock( hTemp);    // Unlock file buffer
  209.                             GlobalFree( hTemp);    // Free file buffer
  210.                             GlobalUnlock( hTemp3);
  211.                             _lclose( hFile);
  212.                             PostMessage( hWnd, WM_CLOSE, NULL, NULL);
  213.                             goto EMERGENCY;
  214.                         }
  215.                         GlobalUnlock( hTemp3);
  216.                         _asm    LES    BX, lpLine
  217.                         _asm    MOV    AX, hTemp3
  218.                         _asm    MOV    WORD PTR ES:[BX], AX     // Save previous line handle
  219.                         _asm    MOV    WORD PTR ES:[BX+2], NULL // Set next line to NULL
  220.                         (WORD) lpLine += FIRSTCHAR;    // skip first FIRSTCHAR bytes
  221.                         if( ++CurrentLine == 0x7FFF)
  222.                         {    CreateMsgBox( hWnd, IDS_ERR_2MANYLINES);
  223.                             goto STOPREADING;
  224.                         }
  225.                     }                // else if carriage return missing, display message.
  226.                     else
  227.                     {    (char) *lpLine = (char) *lpstrTemp;
  228.                         ++((WORD) lpLine);
  229.                         ++((WORD) lpstrTemp);
  230.                     }
  231.                 }
  232.             } // END while()
  233.             // End of buffer was reached: reset lpstrTemp to beginning of buffer:
  234.             (WORD) lpstrTemp = 0;
  235.             goto    READFILE; // Read next portion of file
  236. STOPREADING:        if( lpLine)
  237.             {    // Save the length of the line (a value from FIRSTCHAR-1 to LINELNGTH-1)
  238.                 _asm    MOV    ES, WORD PTR lpLine+2
  239.                 _asm    MOV    AX, WORD PTR lpLine
  240.                 _asm    DEC    AX
  241.                 _asm    MOV    BYTE PTR ES:[FIRSTCHAR-1], AL
  242.                 // Set pointer to next line to NULL
  243.                 _asm    MOV    WORD PTR ES:[2], NULL
  244.                 // Reallocate the line to minimum size...
  245.                 GlobalUnlock( hTemp2);
  246.                 // if the handle is changed and previous line exists
  247.                 // then we must save the new handle
  248.                 GlobalReAlloc( hTemp2, (DWORD)((WORD) lpLine), GMEM_MOVEABLE);
  249.             }
  250. FINITA:            GlobalUnlock( hTemp);
  251.             GlobalFree( hTemp);
  252.             _lclose( hFile);
  253.             NoLines = CurrentLine;
  254.             SetScrollRange( hWnd, SB_VERT, 1, CurrentLine, TRUE);
  255.               }
  256. EMERGENCY:      SetCursor( hOldCursor);
  257.          // Display the file in the window
  258.          InvalidateRect( hWnd, NULL, TRUE);
  259.          UpdateWindow( hWnd);
  260.                  break;
  261.  
  262.             case IDM_F_CLOSE:
  263.          hTemp = hFirstLine;
  264.           while( hTemp)    // Free all of the lines
  265.          {    if( lpLine = (LPSTR) GlobalLock( hTemp))
  266.              {    _asm    LES    BX, lpLine;
  267.                  _asm    MOV    AX, WORD PTR ES:[BX+2]
  268.                  _asm    MOV    hTemp2, AX
  269.              }
  270.              else
  271.                  hTemp2 = NULL;
  272.              GlobalUnlock( hTemp);
  273.              GlobalFree( hTemp);
  274.              hTemp = hTemp2;
  275.          }
  276.          hFirstLine = hCurrentLine = NULL;
  277.          // Clear the window...
  278.          InvalidateRect( hWnd, NULL, TRUE);
  279.          UpdateWindow( hWnd);
  280.                  /* Place User Code to respond to the                   */
  281.                  /* Menu Item Named "&Close" here.                      */
  282.                  break;
  283.  
  284.             case IDM_F_EXITT:
  285.                  /* Place User Code to respond to the                   */
  286.                  /* Menu Item Named "E&xit\t" here.                     */
  287.          SendMessage( hWnd, WM_COMMAND, IDM_F_CLOSE, NULL);
  288.                  PostMessage( hWnd, WM_CLOSE, NULL, NULL);
  289.                  break;
  290.  
  291.             case IDM_F_ABOUT:
  292.                  /* Place User Code to respond to the                   */
  293.                  /* Menu Item Named "&About..." here.                   */
  294.  
  295.  
  296.                  {
  297.                   FARPROC lpfnABOUTMsgProc;
  298.  
  299.                   lpfnABOUTMsgProc = MakeProcInstance((FARPROC)ABOUTMsgProc, hInst);
  300.                   nRc = DialogBox(hInst, MAKEINTRESOURCE(100), hWnd, lpfnABOUTMsgProc);
  301.                   FreeProcInstance(lpfnABOUTMsgProc);
  302.                  }
  303.                  break;
  304.  
  305.             default:
  306.                 return DefWindowProc(hWnd, Message, wParam, lParam);
  307.            }
  308.          break;        /* End of WM_COMMAND                             */
  309.  
  310.     case WM_CREATE:
  311.      SetScrollRange( hWnd, SB_HORZ, 0, 1024, TRUE);
  312.      hCurrentFont = GetStockObject( SYSTEM_FONT);
  313.          break;       /*  End of WM_CREATE                              */
  314.  
  315.     case WM_MOVE:     /*  code for moving the window                    */
  316.          break;
  317.  
  318.     case WM_SIZE:     /*  code for sizing client area                   */
  319.      GetClientRect( hWnd, &rect);
  320.          break;       /* End of WM_SIZE                                 */
  321.  
  322.     case WM_PAINT:    /* code for the window's client area              */
  323.          /* Obtain a handle to the device context                       */
  324.          /* BeginPaint will sends WM_ERASEBKGND if appropriate          */
  325.          hDC = BeginPaint(hWnd, &ps);
  326.  
  327.          /* Included in case the background is not a pure color         */
  328.          SetBkMode(hDC, TRANSPARENT);
  329.      hTemp3 = SelectObject( hDC, hCurrentFont);
  330.       _asm
  331.       {    PUSH    hDC
  332.           PUSH    DS
  333.           PUSH    OFFSET szSpace    // Points to space character
  334.           PUSH    1        // Number of chars. in string
  335.           CALL    GetTextExtent
  336.         MOV    textheight, DX    // Get the space character height
  337.           MOV    spacewidth, AX    // Get the space character width
  338.       }
  339.       // Save the tab stop lenghth (in pixels)
  340.      TabStopLngth = nTabStop*spacewidth;
  341.      hTemp2 = hTemp = hCurrentLine;
  342.      CurrentLine = 0;    // Holds the current Y-screen coordinate
  343.      // Start from top line and go to succesive lines until bottom of screen reached
  344.      hFile = ps.rcPaint.top - textheight;
  345.      while( hTemp && (signed) CurrentLine < ps.rcPaint.bottom)
  346.      {    if( lpLine = GlobalLock( hTemp2 = hTemp))
  347.         {    if( (signed) CurrentLine > (signed) hFile)
  348.             {    _asm
  349.                 {    LES    BX, lpLine
  350.                     MOV    AL, BYTE PTR ES:[BX+4]
  351.                     XOR    AH, AH
  352.                     SUB    AX, (FIRSTCHAR-1)    // AX = nCount
  353.                     JZ    NODRAW
  354.                 // The same as TabbedTextOut( hDC, xoffset, CurrentLine, (LPSTR) lpLine+FIRSTCHAR, nCount, 1, &TabStopLngth, xoffset);
  355.                     PUSH    hDC
  356.                     PUSH    xoffset    // = X-coord
  357.                     PUSH    CurrentLine // = Y-coord.
  358.                     PUSH    ES    // = lpString base
  359.                     PUSH    FIRSTCHAR // = lpString offset
  360.                     PUSH    AX    // = nCount
  361.                     PUSH    1    // = nTabPositions
  362.                     PUSH    DS    // = lpTabStopPositions base
  363.                     PUSH    OFFSET TabStopLngth    // = lpTabStopPositions offset
  364.                     PUSH    xoffset    // = nTabOrigin
  365.                     CALL    TabbedTextOut
  366.                 }
  367.             }
  368. NODRAW:                CurrentLine += textheight;
  369.             _asm    LES    BX, lpLine
  370.             _asm    MOV    AX, WORD PTR ES:[BX+2]
  371.             _asm    MOV    hTemp, AX
  372.             GlobalUnlock( hTemp2);
  373.         }    // END if
  374.         else
  375.             hTemp = NULL;
  376.      }    // END while
  377.      SelectObject( hDC, hTemp3);    // Restore Previous Font
  378.      ValidateRect( hWnd, (LPRECT) NULL);
  379.          /* Inform Windows painting is complete                         */
  380.          EndPaint(hWnd, &ps);
  381.          break;       /*  End of WM_PAINT                               */
  382.  
  383.     case WM_VSCROLL:
  384.          switch(wParam)
  385.            {
  386.         // Set new position to LastLine and update scroll bar
  387.         // (if shown), CB_CURRENTLINE, CBHMEM, MDI Child Window,
  388.         // and status bar.
  389.         case SB_LINEDOWN:
  390.         case SB_PAGEDOWN:
  391.             // Page down only if 2nd-to-last line isn't NULL
  392. PAGEDOWN:         hTemp2 = hTemp = hCurrentLine;
  393.              CurrentLine = 0;    // Holds the current Y-screen coordinate
  394.              i = CurrentLineNo;
  395.              //    Start from top line and go to succesive lines until bottom of screen reached
  396.              while( hTemp && (signed) CurrentLine < rect.bottom)
  397.              {    if( lpLine = GlobalLock( hTemp2 = hTemp))
  398.                 {    CurrentLine += textheight;
  399.                     _asm    LES    BX, lpLine
  400.                     _asm    MOV    AX, WORD PTR ES:[BX+2]
  401.                     _asm    MOV    hTemp, AX
  402.                     _asm    INC    i
  403.                     GlobalUnlock( hTemp2);
  404.                 }    // END if
  405.                 else
  406.                     hTemp = NULL;
  407.              }    // END while
  408.             hCurrentLine = hTemp2;
  409.             CurrentLineNo = --i;
  410.             InvalidateRect( hWnd, NULL, TRUE);
  411.             UpdateWindow( hWnd);
  412.             SetScrollPos( hWnd, SB_VERT, i, TRUE);
  413.             break;
  414.         case SB_LINEUP:
  415.         case SB_PAGEUP:
  416. PAGEUP:            CurrentLine = 0;    // Initialize line number & handle
  417.             hTemp2 = hTemp = hCurrentLine;
  418.             i = CurrentLineNo;
  419.             // Start at bottom and go to preceeding lines until top of screen reached
  420.             while( hTemp && (signed) CurrentLine < rect.bottom)
  421.             {    if( lpLine = GlobalLock( hTemp2 = hTemp))
  422.                 {    CurrentLine += textheight;
  423.                     // Fetch preceding line
  424.                     _asm    LES    BX, lpLine
  425.                     _asm    MOV    AX, WORD PTR ES:[BX]
  426.                     _asm    MOV    hTemp, AX
  427.                     _asm    DEC    WORD PTR i
  428.                     GlobalUnlock( hTemp2);
  429.                 }
  430.                 else
  431.                     hTemp = NULL;
  432.             }
  433.             hCurrentLine = hTemp2;
  434.             SetScrollPos( hWnd, SB_VERT, ++i, TRUE);
  435.             CurrentLineNo = i;
  436.             InvalidateRect( hWnd, &rect, TRUE);
  437.             UpdateWindow( hWnd);
  438.             break;
  439.  
  440.         default:
  441.                 return FALSE;
  442.          }
  443.          break;
  444.  
  445.     case WM_HSCROLL:
  446.          switch (wParam)
  447.            {
  448.         case SB_PAGEDOWN:
  449.         case SB_LINEDOWN:    // Scroll to the right
  450.         xoffset = xoffset - TabStopLngth;
  451.         SetScrollPos( hWnd, SB_HORZ, -xoffset, TRUE);
  452.         ScrollWindow( hWnd, -TabStopLngth, 0, NULL, NULL);
  453.         UpdateWindow( hWnd);
  454.         break;
  455.         case SB_PAGEUP:
  456.         case SB_LINEUP:        // Scroll to the left
  457.         if( (signed) ( j = xoffset + TabStopLngth) > (signed) 0)
  458.             break;
  459.         SetScrollPos( hWnd, SB_HORZ, -(xoffset = j), TRUE);
  460.         ScrollWindow( hWnd, TabStopLngth, 0, NULL, NULL);
  461.         UpdateWindow( hWnd);
  462.         break;
  463.             default:
  464.                  return FALSE;
  465.            }
  466.          break;
  467.  
  468.     case WM_CLOSE:  /* close the window                                 */
  469.          /* Destroy child windows, modeless dialogs, then, this window  */
  470. CLOSE:   DestroyWindow(hWnd);
  471.          if (hWnd == hWndMain)
  472.            PostQuitMessage(0);  /* Quit the application                 */
  473.         break;
  474.  
  475.     default:
  476.          /* For any message for which you don't specifically provide a  */
  477.          /* service routine, you should return the message to Windows   */
  478.          /* for default message processing.                             */
  479.          return DefWindowProc(hWnd, Message, wParam, lParam);
  480.    }
  481.  return 0L;
  482. }     /* End of WndProc                                         */
  483. /************************************************************************/
  484. /*                                                                      */
  485. /* Dialog Window Procedure                                              */
  486. /*                                                                      */
  487. /* This procedure is associated with the dialog box that is included in */
  488. /* the function name of the procedure. It provides the service routines */
  489. /* for the events (messages) that occur because the end user operates   */
  490. /* one of the dialog box's buttons, entry fields, or controls.          */
  491. /*                                                                      */
  492. /************************************************************************/
  493.  
  494. BOOL FAR PASCAL ABOUTMsgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG lParam)
  495. {
  496.  
  497.  switch(Message)
  498.    {
  499.     case WM_INITDIALOG:
  500.          cwCenter(hWndDlg, 0);
  501.          /* initialize working variables                                */
  502.          break; /* End of WM_INITDIALOG                                 */
  503.  
  504.     case WM_CLOSE:
  505.          /* Closing the Dialog behaves the same as Cancel               */
  506.          PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  507.          break; /* End of WM_CLOSE                                      */
  508.  
  509.     case WM_COMMAND:
  510.          switch(wParam)
  511.            {
  512.             case IDCANCEL:
  513.             case IDOK:
  514.                  /* Ignore data values entered into the controls        */
  515.                  /* and dismiss the dialog window returning FALSE       */
  516.                  EndDialog(hWndDlg, FALSE);
  517.                  break;
  518.            }
  519.          break;    /* End of WM_COMMAND                                 */
  520.  
  521.     default:
  522.         return FALSE;
  523.    }
  524.  return TRUE;
  525. } /* End of ABOUTMsgProc                                      */
  526.  
  527.  
  528. /************************************************************************/
  529. /*                                                                      */
  530. /* nCwRegisterClasses Function                                          */
  531. /*                                                                      */
  532. /* The following function registers all the classes of all the windows  */
  533. /* associated with this application. The function returns an error code */
  534. /* if unsuccessful, otherwise it returns 0.                             */
  535. /*                                                                      */
  536. /************************************************************************/
  537.  
  538. int nCwRegisterClasses(void)
  539. {
  540.  WNDCLASS   wndclass;    /* struct to define a window class             */
  541.  memset(&wndclass, 0x00, sizeof(WNDCLASS));
  542.  
  543.  
  544.  /* load WNDCLASS with window's characteristics                         */
  545.  wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
  546.  wndclass.lpfnWndProc = WndProc;
  547.  /* Extra storage for Class and Window objects                          */
  548.  wndclass.cbClsExtra = 0;
  549.  wndclass.cbWndExtra = 0;
  550.  wndclass.hInstance = hInst;
  551.  wndclass.hIcon = LoadIcon(hInst, "EDITPRO");
  552.  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  553.  /* Create brush for erasing background                                 */
  554.  wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  555.  wndclass.lpszMenuName = szAppName;   /* Menu Name is App Name */
  556.  wndclass.lpszClassName = szAppName; /* Class Name is App Name */
  557.  if(!RegisterClass(&wndclass))
  558.    return -1;
  559.  
  560.  
  561.  return(0);
  562. } /* End of nCwRegisterClasses                                          */
  563.  
  564. /************************************************************************/
  565. /*  cwCenter Function                                                   */
  566. /*                                                                      */
  567. /*  centers a window based on the client area of its parent             */
  568. /*                                                                      */
  569. /************************************************************************/
  570.  
  571. void cwCenter(hWnd, top)
  572. HWND hWnd;
  573. int top;
  574. {
  575.  POINT      pt;
  576.  RECT       swp;
  577.  RECT       rParent;
  578.  int        iwidth;
  579.  int        iheight;
  580.  
  581.  /* get the rectangles for the parent and the child                     */
  582.  GetWindowRect(hWnd, &swp);
  583.  GetClientRect(hWndMain, &rParent);
  584.  
  585.  /* calculate the height and width for MoveWindow                       */
  586.  iwidth = swp.right - swp.left;
  587.  iheight = swp.bottom - swp.top;
  588.  
  589.  /* find the center point and convert to screen coordinates             */
  590.  pt.x = (rParent.right - rParent.left) / 2;
  591.  pt.y = (rParent.bottom - rParent.top) / 2;
  592.  ClientToScreen(hWndMain, &pt);
  593.  
  594.  /* calculate the new x, y starting point                               */
  595.  pt.x = pt.x - (iwidth / 2);
  596.  pt.y = pt.y - (iheight / 2);
  597.  
  598.  /* top will adjust the window position, up or down                     */
  599.  if(top)
  600.    pt.y = pt.y + top;
  601.  
  602.  /* move the window                                                     */
  603.  MoveWindow(hWnd, pt.x, pt.y, iwidth, iheight, FALSE);
  604. }
  605.  
  606. /************************************************************************/
  607. /*  CwUnRegisterClasses Function                                        */
  608. /*                                                                      */
  609. /*  Deletes any refrences to windows resources created for this         */
  610. /*  application, frees memory, deletes instance, handles and does       */
  611. /*  clean up prior to exiting the window                                */
  612. /*                                                                      */
  613. /************************************************************************/
  614.  
  615. void CwUnRegisterClasses(void)
  616. {
  617.  WNDCLASS   wndclass;    /* struct to define a window class             */
  618.  memset(&wndclass, 0x00, sizeof(WNDCLASS));
  619.  
  620.  UnregisterClass(szAppName, hInst);
  621. }    /* End of CwUnRegisterClasses                                      */
  622.  
  623.